<?php

declare(strict_types=1);


namespace App\CustHub\Mapper;

use App\CustHub\Model\ChUser;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Config\Annotation\Value;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Collection;
use Hyperf\Database\Model\Model;
use Mine\Abstracts\AbstractMapper;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ChUserMapper extends AbstractMapper
{

    #[Value('cache.default.prefix')]
    protected string $prefix;

    public function assignModel()
    {
        $this->model = ChUser::class;
    }

    /**
     * 根据ID获取用户信息
     * @param mixed $id
     * @return ChUser|Builder|null
     */
    #[Cacheable(prefix: 'cust_hub_user_info',value: 'id_#{id}')]
    public function findById(mixed $id): ChUser|Builder|null
    {
        return $this->model::with(['ext'])->where('id',$id)->first();
    }

    /**
     * 删除用户缓存
     * @param mixed $id
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \RedisException
     */
    public function clearCache(mixed $id): void
    {
        $redis = redis();
        $keyOne = $this->prefix . 'cust_hub_user_info:id_'.$id;
        $redis->del([$keyOne]);
    }


    /**
     * 通过openid检查用户
     * @param string $openid
     * @return array
     */
    public function findByOpenid(string $openid): array
    {
        $userInfo = $this->model::query()->where('openid', $openid)->first();
        return empty($userInfo) ? [] : $userInfo->toArray();
    }

    /**
     * 通过手机号检查用户
     * @param string $mobile
     * @return array
     */
    public function findByMobile(string $mobile): array
    {
        $userInfo = $this->model::query()->where('mobile', $mobile)->first();
        return empty($userInfo) ? [] : $userInfo->toArray();
    }

    public function findByAccount(string $account): array
    {
        $userInfo = $this->model::query()->where('account', $account)->firstOrFail();
        return empty($userInfo) ? [] : $userInfo->toArray();
    }

    /**
     * 检查手机号是否存在
     * @param string $mobile
     * @return bool
     */
    public function checkMobileExist(string $mobile): bool
    {
        return $this->model::query()->where('mobile', $mobile)->exists();
    }

    /**
     * 通过邀请码获取用户信息
     * @param string $inviteCode
     * @return ChUser|Model|string|Builder|null
     */
    public function findByInviteCode(string $inviteCode): ChUser|Model|string|Builder|null
    {
        return $this->model::query()->where('invite_code',$inviteCode)->first();
    }

    /**
     * 检查用户密码
     */
    public function checkPass(string $password, string $hash): bool
    {
        return $this->model::passwordVerify($password, $hash);
    }

    /**
     * 获取子账号列表
     * @param int $mainUid
     * @param array $fields
     * @return array|Collection|\Hyperf\Collection\Collection
     */
    public function getSubUserList(int $mainUid,array $fields = ['*']): array|Collection|\Hyperf\Collection\Collection
    {
        return $this->model::query()
            ->select($fields)
            ->with(['ext'])
            ->where('parent_id',$mainUid)
            ->orderBy('created_at','desc')
            ->get();
    }

    /**
     * 初始化用户密码
     */
    public function initUserPassword(int $id, string $password): bool
    {
        $model = $this->model::find($id);
        if ($model) {
            $model->password = $password;
            return $model->save();
        }
        return false;
    }

    /**
     * 获取主账号ID
     */
    public function getMainUid(int $uid)
    {
        $user = $this->findById($uid);
        $parent_id = $user->parent_id;
        if ($parent_id == 0) {
            return $uid;
        } else {
            return $parent_id;
        }
    }

    /**
     * 增加用户席位数
     * @param int $id
     * @param int $seatNum
     * @param int $type
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws \RedisException
     */
    public function inc(int $id,int $seatNum,int $type = 0): void
    {
        $column = $type == 0 ? 'seat_count' : 'corp_seat_count';
        $this->model::query()->where('id',$id)->increment($column,$seatNum);
        $this->clearCache($id);
    }
}